package org.example.gui;

import lombok.Getter;
import lombok.Setter;
import org.example.constant.OcrItem;
import org.example.context.OcrApplicationContext;

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.filechooser.FileFilter;
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Arrays;

@Getter
@Setter
public class CaptureScreen extends JFrame implements ActionListener {
    private JPanel panel;
    private BufferedImage image;
    private JButton start, cancel, copy;
    private final JTextArea text = new JTextArea();
    private JMenuItem defaultItem, tessItem, baiduItem, selectItem;


    {
        // 设置图标
        try {
            URL resource = Thread.currentThread().getContextClassLoader().getResource("static/icon.jpg");
            if (null == resource) {
                // 兼容ide环境
                resource = this.getClass().getResource("/static/icon.jpg");
            }
            this.setIconImage(ImageIO.read(resource));
        } catch (IOException e) {

        }
        // 内容识别区
        text.setOpaque(false);
        text.setEditable(false);
        text.setBorder(BorderFactory.createTitledBorder("内容识别区"));
        text.setPreferredSize(new Dimension(300, 100));
        text.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseEntered(MouseEvent e) {
                text.setCursor(new Cursor(Cursor.TEXT_CURSOR));
            }

            @Override
            public void mouseExited(MouseEvent e) {
                text.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
            }
        });
    }

    /**
     * Creates a new instance of CaptureScreen
     */
    public CaptureScreen() {
        super("OCR图像识别");
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
            e.printStackTrace();
        }
        initWindow();
        OcrApplicationContext.setFrame(this);
    }

    @Override
    public void actionPerformed(ActionEvent ae) {
        Object source = ae.getSource();
        if (source == start) {
            doStart();
        } else if (source == cancel) {
            text.setText("");
        } else if (source == copy) {
            doCopyButton(text.getText());
        }
    }


    private void initWindow() {
        defaultItem = new JRadioButtonMenuItem(OcrItem.DEFAULT.getDesc(), true);
        tessItem = new JRadioButtonMenuItem(OcrItem.TESS.getDesc());
        baiduItem = new JRadioButtonMenuItem(OcrItem.BAIDU.getDesc());

        defaultItem.addActionListener(new JRadioButtonMenuItemActionListener(OcrItem.DEFAULT));
        tessItem.addActionListener(new JRadioButtonMenuItemActionListener(OcrItem.TESS));
        baiduItem.addActionListener(new JRadioButtonMenuItemActionListener(OcrItem.BAIDU));

        ButtonGroup group = new ButtonGroup();
        group.add(defaultItem);
        group.add(tessItem);
        group.add(baiduItem);


        JMenu source = new JMenu("OCR源");
        source.add(defaultItem);
        source.add(tessItem);
        source.add(baiduItem);

        JMenuItem config = new JMenuItem("配置");
        config.addActionListener(e -> {
            if (!System.getProperty("os.name").startsWith("Windows")) {
                return;
            }
            try {
                Runtime.getRuntime().exec("notepad " + System.getProperty("user.dir") + "\\" + "config.ini");
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }
        });

        JMenu options = new JMenu("选项(O)");
        options.addSeparator();
        options.add(source);
        options.add(config);

        JMenu about = new JMenu("关于(A)");

        JMenuBar menuBar = new JMenuBar();
        menuBar.add(options);
        menuBar.add(about);
        this.setJMenuBar(menuBar);

        copy = new JButton("复制");
        start = new JButton("识别");
        cancel = new JButton("清空");
        start.addActionListener(this);
        start.setMnemonic(KeyEvent.VK_A);
        cancel.addActionListener(this);
        copy.addActionListener(this);


        JLabel jl = new JLabel("屏幕截取", JLabel.CENTER);
        jl.setFont(new Font("黑体", Font.BOLD, 40));
        jl.setForeground(Color.RED);

        panel = new JPanel(new BorderLayout());
        panel.add(jl, BorderLayout.CENTER);

        JPanel buttonJP = new JPanel();
        buttonJP.add(start);
        buttonJP.add(copy);
        buttonJP.add(cancel);
        buttonJP.setBorder(BorderFactory.createTitledBorder("公共操作区"));
        buttonJP.setPreferredSize(new Dimension(120, 100));

        JPanel all = new JPanel();
        all.add(text);
        all.add(buttonJP);

        this.getContentPane().add(panel, BorderLayout.CENTER);
        this.getContentPane().add(all, BorderLayout.SOUTH);
        this.setSize(500, 400);
        this.setLocationRelativeTo(null);
        this.setVisible(true);
        this.setAlwaysOnTop(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    void updates() {
        setVisible(true);
        if (image != null) {
            panel.removeAll();
            panel.add(new PicturePanel(image, this), BorderLayout.CENTER);
            // 调整LookAndFeel（javax.swing）
            SwingUtilities.updateComponentTreeUI(panel);
        }
    }

    private void doStart() {
        try {
            this.setVisible(false);
            // 睡500毫秒是为了让主窗完全不见
            Thread.sleep(500);
            // （通过本地操作）控制鼠标、键盘等实际输入源（java.awt）
            Robot ro = new Robot();
            // AWT组件的抽象父类（java.awt）
            Dimension di = Toolkit.getDefaultToolkit().getScreenSize();
            Rectangle rec = new Rectangle(0, 0, di.width, di.height);
            BufferedImage bi = ro.createScreenCapture(rec);
            JFrame jf = new JFrame();
            // 自定义的Temp类的对象
            Temp temp = new Temp(jf, bi, this, di.width, di.height);
            jf.getContentPane().add(temp, BorderLayout.CENTER);
            jf.setUndecorated(true);
            jf.setAlwaysOnTop(true);
            jf.setVisible(true);
            jf.setSize(di);
        } catch (Exception exe) {
            exe.printStackTrace();
        }
    }


    /**
     * 公用的处理保存图片的方法
     */
    public void doSave(BufferedImage get) {
        if (get == null) {
            JOptionPane.showMessageDialog(this, "图片不能为空!!", "错误", JOptionPane.ERROR_MESSAGE);
            return;
        }
        JFileChooser jfc = new JFileChooser(".");
        Arrays.stream(PictureTypeFilter.Type.values()).forEach(v -> jfc.addChoosableFileFilter(new PictureTypeFilter(v)));
        int state = jfc.showSaveDialog(this);
        if (state != JFileChooser.APPROVE_OPTION) {
            return;
        }
        String about = "PNG";
        File file = jfc.getSelectedFile();
        FileFilter ff = jfc.getFileFilter();
        if (ff instanceof PictureTypeFilter) {
            String ext = file.toString().toLowerCase();
            PictureTypeFilter custom = (PictureTypeFilter) ff;
            if (!PictureTypeFilter.contains(ext)) {
                file = new File(ext + custom.getType().getSuffix());
                about = custom.getType().getDesc();
            }
        }

        try {
            if (ImageIO.write(get, about, file)) {
                JOptionPane.showMessageDialog(this, "保存成功！");
            } else {
                JOptionPane.showMessageDialog(this, "保存失败！");
            }
        } catch (IOException e) {
            JOptionPane.showMessageDialog(this, "保存失败！");
        }
    }

    /**
     * 公共的处理把当前的图片加入剪帖板的方法
     */
    public void doCopy(final BufferedImage image) {
        if (this.image == null) {
            JOptionPane.showMessageDialog(this, "图片不能为空!!", "错误", JOptionPane.ERROR_MESSAGE);
            return;
        } // java.awt.datatransfer（接口）
        // 内部类
        Transferable trans = new Transferable() {
            @Override
            public DataFlavor[] getTransferDataFlavors() {
                return new DataFlavor[]{DataFlavor.imageFlavor};
            }

            @Override
            public boolean isDataFlavorSupported(DataFlavor flavor) {
                return DataFlavor.imageFlavor.equals(flavor);
            }

            @Override
            public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException {
                if (isDataFlavorSupported(flavor)) {
                    return image;
                }
                throw new UnsupportedFlavorException(flavor);
            }
        };

        Toolkit.getDefaultToolkit().getSystemClipboard().setContents(trans, null);
        JOptionPane.showMessageDialog(this, "已复制到系统粘帖板!!");
    }

    //处理关闭事件
    public void doClose(Component c) {
        c = null;
        System.gc();
    }

    private void doCopyButton(final String readeResult) {
        if (null == readeResult || "".equals(readeResult.trim())) {
            return;
        }
        // 内部类
        Transferable trans = new Transferable() {
            @Override
            public DataFlavor[] getTransferDataFlavors() {
                return new DataFlavor[]{DataFlavor.stringFlavor};
            }

            @Override
            public boolean isDataFlavorSupported(DataFlavor flavor) {
                return DataFlavor.stringFlavor.equals(flavor);
            }

            @Override
            public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException {
                if (isDataFlavorSupported(flavor)) {
                    return readeResult;
                }
                throw new UnsupportedFlavorException(flavor);
            }
        };

        Toolkit.getDefaultToolkit().getSystemClipboard().setContents(trans, null);
        JOptionPane.showMessageDialog(this, "已复制到系统粘帖板!!");
    }
}